#include "stdafx.h"
#include "stdlib/bugcheck.hpp"
#include "stdlib/debugger.hpp"
#include "stdlib/exception.hpp"
#include <sstream>

namespace JHCPP
{
	namespace stdlib
	{
		void CBugCheck::assertion(const char* cond, const char* file, int line)
		{
			CDebugger::enter(std::string("Assertion violation: ") + cond, file, line);
			throw jhException::AssertionViolationException(what(cond, file, line));
		}

		void CBugCheck::nullPointer(const char* ptr, const char* file, int line)
		{
			CDebugger::enter(std::string("NULL pointer: ") + ptr, file, line);
			throw jhException::NullPointerException(what(ptr, file, line));
		}

		void CBugCheck::bugcheck(const char* file, int line)
		{
			CDebugger::enter("BugCheck", file, line);
			throw jhException::BugcheckException(what(0, file, line));
		}

		void CBugCheck::bugcheck(const char* msg, const char* file, int line)
		{
			std::string m("BugCheck");
			if (msg)
			{
				m.append(": ");
				m.append(msg);
			}
			CDebugger::enter(m, file, line);
			throw jhException::BugcheckException(what(msg, file, line));
		}

		void CBugCheck::unexpected(const char* file, int line)
		{
		#ifdef _DEBUG
			try
			{
				std::string msg("Unexpected exception in noexcept function or destructor: ");
				try
				{
					throw;
				}
				catch (CException& exc)
				{
					msg += exc.displayText();
				}
				catch (std::exception& exc)
				{
					msg += exc.what();
				}
				catch (...)
				{
					msg += "unknown exception";
				}
				CDebugger::enter(msg, file, line);
			}
			catch (...)
			{
			}
		#endif	
		}

		void CBugCheck::debugger(const char* file, int line)
		{
			CDebugger::enter(file, line);
		}

		void CBugCheck::debugger(const char* msg, const char* file, int line)
		{
			CDebugger::enter(msg, file, line);
		}

		std::string CBugCheck::what(const char* msg, const char* file, int line)
		{
			std::ostringstream str;
			if (msg) str << msg << " ";
			str << "in file \"" << file << "\", line " << line;
			return str.str();
		}

	}//end of namespace stdlib
}//end of namespace JHCPP